﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;

namespace JeanFish.Data.Common
{
    public class DbProviderManifest : System.Data.Common.DbProviderManifest
    {
        private string providerName;
        private System.Data.Common.DbProviderManifest providerManifest;
        private string decoratorProviderName;

        public DbProviderManifest(string decoratorProviderName, string providerName, System.Data.Common.DbProviderManifest providerManifest)
        {
            this.decoratorProviderName = decoratorProviderName;
            this.providerManifest = providerManifest;
            this.providerName = providerName;
        }

        public override string NamespaceName
        {
            get { return this.ProviderManifest.NamespaceName; }
        }

        public System.Data.Common.DbProviderManifest ProviderManifest
        {
            get { return this.providerManifest; }
        }

        public string DecoratorProviderName
        {
            get
            {
                return this.decoratorProviderName;
            }
        }
        public override System.Data.Metadata.Edm.TypeUsage GetEdmType(System.Data.Metadata.Edm.TypeUsage storeType)
        {
            return this.ProviderManifest.GetEdmType(storeType);
        }

        public override System.Collections.ObjectModel.ReadOnlyCollection<System.Data.Metadata.Edm.FacetDescription> GetFacetDescriptions(System.Data.Metadata.Edm.EdmType edmType)
        {
            return this.ProviderManifest.GetFacetDescriptions(edmType);
        }

        public override System.Collections.ObjectModel.ReadOnlyCollection<System.Data.Metadata.Edm.EdmFunction> GetStoreFunctions()
        {
            return this.ProviderManifest.GetStoreFunctions();
        }
        public override System.Data.Metadata.Edm.TypeUsage GetStoreType(System.Data.Metadata.Edm.TypeUsage edmType)
        {
            return this.ProviderManifest.GetStoreType(edmType);
        }

        public override System.Collections.ObjectModel.ReadOnlyCollection<System.Data.Metadata.Edm.PrimitiveType> GetStoreTypes()
        {
            return this.ProviderManifest.GetStoreTypes();
        }

        public override string ToString()
        {
            return "DecoratedProviderManifest(Wrapped=" + this.ProviderManifest + ")";
        }

        public override bool SupportsEscapingLikeArgument(out char escapeCharacter)
        {
            return this.ProviderManifest.SupportsEscapingLikeArgument(out escapeCharacter);
        }

        public override string EscapeLikeArgument(string argument)
        {
            return this.ProviderManifest.EscapeLikeArgument(argument);
        }

        protected override XmlReader GetDbInformation(string informationType)
        {
            if (informationType == System.Data.Common.DbProviderManifest.StoreSchemaDefinition)
            {
                return this.InjectProviderNameIntoSsdl(this.ProviderManifest.GetInformation(informationType));
            }
            return this.ProviderManifest.GetInformation(informationType);
        }

        private XmlReader InjectProviderNameIntoSsdl(XmlReader oldReader)
        {
            XElement ssdl = XElement.Load(oldReader);
            ssdl.Attribute("ProviderManifestToken").Value = ssdl.Attribute("Provider").Value + ";" + ssdl.Attribute("ProviderManifestToken").Value;
            ssdl.Attribute("Provider").Value = this.decoratorProviderName;
            return ssdl.CreateReader();
        }
    }
}
